var keycodeMap = {
	DOWN: 40,
	ENTER: 13,
	LEFT: 37,
	NUMPAD_ENTER: 108,
	RIGHT: 39,
	UP: 38,
};


var defaultSettings = {
	itemClass: "autocomplete-item",
	activeItemClass: "autocomplete-item___active",
	
	render: function(data, settings){
		var element = $("<ul />"),
			classname = settings.itemClass;
		
		$.each(data, function(_, text){
			$("<li />").text(text).addClass(classname).appendTo(element);
		});
		return element;
	},
	
	getNextActiveItem: function(event, context, prevActiveItem, settings){
		var keycode = event.keyCode,
			items = $("." + settings.itemClass, context),
			len = items.length,
			prevActiveIndex = $.inArray(prevActiveItem && prevActiveItem[0], items),
			activeIndex,
			activeItem;
		
		if(keycode === keycodeMap.UP){
			activeIndex = prevActiveIndex > -1 ? prevActiveIndex - 1 : len - 1;
		}
		
		if(keycode === keycodeMap.DOWN){
			activeIndex = prevActiveIndex === len - 1 ? -1 : prevActiveIndex + 1; 
		}
		
		return $(items[activeIndex]);
	}
};


$.fn.autocomplete = function(customSettings){
	var input = $(this[0]),
		settings = $.extend(true, {}, defaultSettings, customSettings),
		originalValue = input.val(),
		element;
	
	element = $("<div class=autocomplete />").appendTo("body");
	
	input.bind("keyup", function(event){
		var keycode = event.keyCode,
			activeItemClass = settings.activeItemClass,
			value = input.val();
		
		switch(keycode){
		case keycodeMap.UP:
		case keycodeMap.DOWN:
			var prevActiveItem = $("." + settings.activeItemClass, element), 
				nextActiveItem = settings.getNextActiveItem(event, element, prevActiveItem, settings);
				
			
			prevActiveItem.removeClass(activeItemClass);
			nextActiveItem.addClass(activeItemClass);
			input.val(nextActiveItem.length ? nextActiveItem.text() : originalValue);
			break;
			
		default:
			if(originalValue !== value){
				originalValue = value;
				$.ajax({
					url: settings.source,
					data: {term: value},
					success: function(data){
						var content = settings.render(data, settings);
						element.empty().append(content);
					}
				});
			}
		}
	});
};





